// 
//  MainWindow.cs
//  
//  Author:
//       Christopher Sawyer <christoofar@gmail.com>
//  
//  LGPL, Christopher Sawyer (2010)
// 
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
// 
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU Lesser General Public License for more details.
// 
//  You should have received a copy of the GNU Lesser General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
using System;
using Gtk;
using Mono.SANE;

public partial class MainWindow : Gtk.Window
{
	private Scanner currentScanner = null;
	
	public MainWindow () : base(Gtk.WindowType.Toplevel)
	{
		Build ();
		FindScanners ();
	}

	protected void OnDeleteEvent (object sender, DeleteEventArgs a)
	{
		Application.Quit ();
		a.RetVal = true;
	}

	protected virtual void FindScanners ()
	{
		Console.WriteLine (SANEControl.IsSANEAvailable);
		Console.WriteLine (SANEControl.Scanners.Count);
		
		Gtk.ListStore store = new Gtk.ListStore (typeof(string), typeof(Scanner));
		combobox1.Model = store;
		
		foreach (Scanner scanner in SANEControl.Scanners.Values) {
			store.AppendValues (new object[] { scanner.Deviceid, scanner });
		}
		
		Gtk.TreeIter first;
		store.GetIterFirst (out first);
		
		if (SANEControl.Scanners.Count == 0)
		{
			button1.Visible = false;
			buttonTest.Visible = false;
			
			Gtk.MessageDialog dlg = new Gtk.MessageDialog (this, DialogFlags.Modal, MessageType.Error, 
				ButtonsType.Ok, "SANE could not find any scanners on your computer.");
			dlg.Run ();
			dlg.Destroy ();
		} 
		else 
		{
			combobox1.SetActiveIter (first);
			OnCombobox1Changed (null, null);
		}
	}

	protected virtual void OnButtonTestClicked (object sender, System.EventArgs e)
	{
		// Get the selected scanner
		Gtk.TreeIter currentItem;
		combobox1.GetActiveIter (out currentItem);
		
		object data = combobox1.Model.GetValue (currentItem, 1);
		Scanner scanner = (Scanner)data;
		
		// Scan a picture
		Gdk.Pixbuf picture;
		try
		{
			picture = scanner.ScanPicture ();

			Window picWin = new Window (WindowType.Popup);
			Gtk.Image img = new Gtk.Image (picture);
			picWin.Add (img);
			picWin.ShowAll ();
			picWin.ShowNow ();
		} 
		catch (NoDocumentLoadedException) 
		{
			Gtk.MessageDialog dlg = new Gtk.MessageDialog (this, DialogFlags.Modal,
				MessageType.Error, ButtonsType.Ok, "No pages were loaded in the scanner.");
			dlg.Run ();
			dlg.Destroy ();
		}
	
	}

	protected virtual void OnCombobox1Changed (object sender, System.EventArgs e)
	{
		while (vbox1.Children.Length > 0) {
			vbox1.Remove (vbox1.Children[0]);
		}
		
		Gtk.TreeIter currentItem;
		combobox1.GetActiveIter (out currentItem);
		
		object data = combobox1.Model.GetValue (currentItem, 1);
		Scanner scanner = (Scanner)data;
		
		foreach (ScannerOption option in scanner.Options.Values) {
			HBox box = new HBox (false, 5);
			box.PackStart (new Label (option.Switch));
			ComboBox cbox = new ComboBox (option.AvailableOptions);
			
			for (int i = 0; i < option.AvailableOptions.Length; i++) {
				if (option.AvailableOptions[i] == option.CurrentSetting) {
					cbox.Active = i;
					break;
				}
			}
			
			box.PackEnd (cbox);
			box.ShowAll ();
			
			vbox1.PackEnd (box);
		}
	}
	
	protected virtual void OnButton1Clicked (object sender, System.EventArgs e)
	{
		// Get the selected scanner
		Gtk.TreeIter currentItem;
		combobox1.GetActiveIter (out currentItem);
		
		object data = combobox1.Model.GetValue (currentItem, 1);
		currentScanner = (Scanner)data;
		
		currentScanner.ScanningProgress += HandleScannerScanningProgress;
		currentScanner.PageScanCompleted += HandleScannerPageScanCompleted;
		currentScanner.PagesScanned += HandleScannerPagesScanned;
		currentScanner.BatchScanCompleted += HandleScannerBatchScanCompleted;
		
		progressbar1.Text = "Starting scan...";
		
		currentScanner.StartMultiPageScan ();
	}
	
	void ReleaseHooks ()
	{
		currentScanner.ScanningProgress -= HandleScannerScanningProgress;
		currentScanner.PageScanCompleted -= HandleScannerPageScanCompleted;
		currentScanner.PagesScanned -= HandleScannerPagesScanned;
		currentScanner.BatchScanCompleted -= HandleScannerBatchScanCompleted;		
	}
	
	void HandleScannerBatchScanCompleted ()
	{
		Gtk.Application.Invoke (delegate { 
			progressbar1.Text = "Scan completed!";
		});
		
		ReleaseHooks ();
	}

	void HandleScannerPagesScanned (int pages)
	{
		Gtk.Application.Invoke (delegate {
			label3.Text = pages.ToString ();
			label3.Show();
		});
	}

	void HandleScannerPageScanCompleted (string imageFileName)
	{	
		Gtk.Application.Invoke (delegate {
			Console.WriteLine ("Scanned image located at: " + imageFileName);
		});
	}

	void HandleScannerScanningProgress (double progress)
	{	
		Gtk.Application.Invoke (delegate {
			progressbar1.Fraction = progress/100;
			progressbar1.Text = progress.ToString() + "%";
			progressbar1.Show();
		});
	}
	
	
	
	
}
